
<template>
  <div class="dify-container">
    <el-card shadow="always">
      <div slot="header" class="clearfix">
        <span>销售数据分析</span>
        <el-button-group style="float: right">
          <el-button
            type="primary"
            size="small"
            @click="startStream"
            :loading="loading"
            :disabled="isStreaming"
          >
            {{ isStreaming ? '生成中...' : '开始分析' }}
          </el-button>
          <el-button
            v-if="isStreaming"
            size="small"
            @click="stopStream"
          >
            停止
          </el-button>
        </el-button-group>
      </div>

      <el-input
        v-model="query"
        placeholder="请输入分析指令"
        clearable
        class="query-input"
      ></el-input>

      <el-divider></el-divider>

      <div class="response-box">
        <div
          v-if="content"
          class="html-content"
          v-html="purifiedContent"
          ref="contentEl"
        ></div>
        <el-empty
          v-else
          description="输入问题后点击开始分析"
        ></el-empty>
      </div>
    </el-card>
  </div>
</template>

<script>
import DOMPurify from 'dompurify'

export default {
  data() {
    return {
      query: '根据客户维度分析排名前五的业绩分布情况',
      content: '',
      loading: false,
      isStreaming: false,
      eventSource: null
    }
  },
  computed: {
    purifiedContent() {
      // 安全净化HTML内容
      return DOMPurify.sanitize(this.content)
    }
  },
  methods: {
    startStream() {
      if (this.isStreaming) return
      if (!this.query.trim()) {
        this.$message.warning('请输入分析内容')
        return
      }

      this.loading = true
      this.isStreaming = true
      this.content = ''

      // 构造请求参数
      const payload = {
        inputs: {},
        query: this.query,
        response_mode: 'streaming',
        user: 'abc-123'
      }

      // 创建EventSource连接
      this.createEventSource(payload)
    },

    createEventSource(payload) {
      // 使用fetch API处理流式响应
      fetch('http://agent.toasin.cn/v1/chat-messages', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer app-diDqt5qIyV9aXyykETv3Sdgh'
        },
        body: JSON.stringify(payload)
      })
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`)
          }

          const reader = response.body.getReader()
          const decoder = new TextDecoder('utf-8')

          const processStream = ({done, value}) => {
            if (done) {
              this.stopStream()
              return
            }

            const chunk = decoder.decode(value, {stream: true})

            try {
              // 处理可能的多条消息合并情况
              chunk.split('\n').forEach(line => {
                if (line.startsWith('data:')) {
                  const data = JSON.parse(line.substring(5).trim())
                  if (data.event === 'message' && data.answer) {
                    this.content += data.answer
                    this.$nextTick(this.scrollToBottom)
                  }
                }
              })
            } catch (e) {
              console.error('解析错误:', e)
            }

            // 继续读取下一块数据
            return reader.read().then(processStream)
          }

          return reader.read().then(processStream)
        })
        .catch(err => {
          console.error('请求失败:', err)
          this.$message.error(`请求失败: ${err.message}`)
          this.stopStream()
        })
        .finally(() => {
          this.loading = false
        })
    },

    stopStream() {
      this.isStreaming = false
      if (this.eventSource) {
        this.eventSource.close()
        this.eventSource = null
      }
    },

    scrollToBottom() {
      const el = this.$refs.contentEl
      if (el) {
        el.scrollTop = el.scrollHeight
      }
    }
  },
  beforeDestroy() {
    this.stopStream()
  }
}
</script>

<style scoped>
.dify-container {
  max-width: 900px;
  margin: 20px auto;
  padding: 0 15px;
}

.query-input {
  margin-bottom: 20px;
}

.response-box {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 20px;
  min-height: 300px;
  max-height: 500px;
  overflow-y: auto;
}

.html-content >>> table {
  width: 100%;
  border-collapse: collapse;
  margin: 10px 0;
}

.html-content >>> th,
.html-content >>> td {
  border: 1px solid #dfe6ec;
  padding: 8px 12px;
}

.html-content >>> pre {
  background: #f5f7fa;
  padding: 12px;
  border-radius: 4px;
  overflow-x: auto;
}

/* 美化滚动条 */
.response-box::-webkit-scrollbar {
  width: 8px;
}

.response-box::-webkit-scrollbar-thumb {
  background-color: #c0c4cc;
  border-radius: 4px;
}
</style>
